package org.reliablesource.prism.core.plugin;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Writer;

import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext;
import org.reliablesource.prism.core.IPrismElementFactory;
import org.reliablesource.prism.core.IPrismModel;
import org.reliablesource.prism.core.IPrismTutorial;
import org.reliablesource.prism.core.internal.PrismElementFactory;

/**
 * The main plugin class to be used in the desktop.
 */
public class PrismCorePlugin extends Plugin {

	public static final Object[] NULL_OBJECT = new Object[0];

	// The shared instance.
	private static PrismCorePlugin plugin;

	private static IPrismElementFactory elementFactory;

	// NOTE: Keep this model's scope of visibility to this package ONLY!
	private static IPrismModel model;
	
	public final static String LINE_SEPERATOR = System.getProperty("line.separator");

	/**
	 * The constructor.
	 */
	public PrismCorePlugin() {
		plugin = this;
	}

	/**
	 * This method is called upon plug-in activation
	 */
	public void start(BundleContext context) throws Exception {
		super.start(context);
		elementFactory = new PrismElementFactory();
		model = elementFactory.createModel();
		
		// model.getTutorials().add(elementFactory.createTestTutorialNode());
	}

	/**
	 * This method is called when the plug-in is stopped
	 */
	public void stop(BundleContext context) throws Exception {
		super.stop(context);
		plugin = null;
	}

	/**
	 * Returns the shared instance.
	 */
	public static PrismCorePlugin getDefault() {
		return plugin;
	}

	public IPrismElementFactory getElementFactory() {
		return elementFactory;
	}

	public IPrismModel getModel() {
		return model;
	}

	public void saveTutorial(IPrismTutorial tutorial, String savePath) throws IOException {
		File saveTo = new File(savePath);

			if (!saveTo.exists())
				saveTo.createNewFile();
			        FileOutputStream f = new FileOutputStream(saveTo);
			        ObjectOutputStream s = new ObjectOutputStream(f); 
			        try{
			        	
			        	s.writeObject(tutorial); 
			        	s.flush();
			        }finally{
			        s.close();
			        }
	}

	public IPrismTutorial loadTutorial(String loadPath) throws FileNotFoundException, IOException, ClassNotFoundException{
		return (IPrismTutorial) readData(loadPath);
	}

	/**
	 * Change the contents of text file in its entirety, overwriting any
	 * existing text.
	 * 
	 * This style of implementation throws all exceptions to the caller.
	 * 
	 * @param _aFile
	 *            is an existing file which can be written to.
	 * @throws IllegalArgumentException
	 *             if param does not comply.
	 * @throws FileNotFoundException
	 *             if the file does not exist.
	 * @throws IOException
	 *             if problem encountered during write.
	 */
	private void setContents(final File _aFile, final String tutorial)
			throws IOException, IllegalArgumentException {
		if (_aFile == null) 
			throw new IllegalArgumentException("File should not be null.");
		if (!_aFile.exists()) 
			throw new FileNotFoundException("File does not exist: " + _aFile);
		if (!_aFile.isFile()) 
			throw new IllegalArgumentException("Should not be a directory: "+ _aFile);
		if (!_aFile.canWrite()) 
			throw new IllegalArgumentException("File cannot be written: " + _aFile);

		// declared here only to make visible to finally clause; generic
		// reference
		Writer output = new BufferedWriter(new FileWriter(_aFile));
		try {
			output.write(tutorial);
		} finally {
			// flush and close both "output" and its underlying FileWriter
				output.close();
		}
	}
	
//	 Reading an Object from a stream. 
//	 Deserialize a String and date from a file. 
	 
	public Object  readData(String _resource)
	            throws IOException, ClassNotFoundException { 
	        FileInputStream in = new FileInputStream(_resource); 
	        ObjectInputStream s = new ObjectInputStream(in); 
	       return s.readObject();
	       
	} 

}
